package br.org.bertol.mestrado;

import java.util.concurrent.CountDownLatch;

import br.org.bertol.mestrado.engine.EnginePso;
import br.org.bertol.mestrado.engine.fitness.Objective;
import br.org.bertol.mestrado.util.Configurator;
import br.org.bertol.mestrado.util.PsoConfiguration;

/**
 * @author contaqualquer
 */
public class StarterPSO extends AbstractStarter<EnginePso> {

    public StarterPSO(Configurator configurator) {
        super(configurator);
    }

    /**
     */
    @Override
    public void startEngine() throws InterruptedException {
        startPsoEngineBySystem(configurator.getIteracoes(), configurator
                .getSourcePath());
    }

    /**
     * @param avaliacoes
     * @param sourePath
     * @throws InterruptedException
     */
    public final void startPsoEngineBySystem(final int avaliacoes,
            final String sourePath) throws InterruptedException {
        for (String system : configurator.getSystems()) {

            final PsoConfiguration psoConfiguration = configurator
                    .loadPsoConfiguration(system);

            startPsoEngineByInput(avaliacoes, sourePath, system,
                                  psoConfiguration);
        }
    }

    /**
     * @param avaliacoes
     * @param sourePath
     * @param system
     * @throws InterruptedException
     */
    public void startPsoEngineByInput(final int avaliacoes,
            final String sourePath, final String system,
            final PsoConfiguration psoConfig)
            throws InterruptedException {
        for (Objective[] objectives : configurator.getObjectives()) {
            startPsoEngine(objectives, avaliacoes, sourePath, system,
                           psoConfig);
        }
    }

    /**
     * @param typeMovement
     * @param constraint
     * @param avaliacoes
     * @param sourePath
     * @param system
     * @throws InterruptedException
     *             Caso ocorra algum erro ao sincronizar as threads
     */
    public void startPsoEngine(
            final Objective[] constraint, final int avaliacoes,
            final String sourePath, final String system,
            final PsoConfiguration psoConfig)
            throws InterruptedException {

        final CountDownLatch systemstart = new CountDownLatch(1);

        final CountDownLatch systemstop = new CountDownLatch(1);

        // inicia pso
        final EnginePso enginePso = new EnginePso(systemstart, systemstop,
                avaliacoes,
                constraint, sourePath, system, psoConfig);

        enginePso.start();

        // notifica threads que
        // buscas podem iniciar
        systemstart.countDown();

        // coloca sistema em modo de espera
        // pela conclus�o das buscas
        systemstop.await();

        // adiciona na lista de solu��es
        engineList.add(enginePso);
    }
}
